package org.jod.anarchytrek.component;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.jod.anarchytrek.AComponent;
import org.jod.anarchytrek.IConsumerableComponent;
import org.jod.anarchytrek.ISupplierableComponent;
import org.jod.anarchytrek.ITimerableComponent;
import org.jod.anarchytrek.ITurnableComponent;
import org.jod.anarchytrek.info.EpsInfo;

public class Eps extends AComponent  implements ITurnableComponent, ITimerableComponent { 

    static final int BASE_STRUCTURED_UNITS = 5;
    private static final int TRANSFER_ENERGY_UNIT = 10;
    private String _status;
    private EpsInfo _epsInfo;
    private List _supplierList;
    private List _consumerList;
    private int _flow;
    private int _amountEnergy ;
    private int _amountEnergySupplied ;
    private int _amountEnergyConsumed ;
    
    public Eps(int aShipClass, EpsInfo aInfo, int extraStructuralUnits) {
        super(aShipClass * BASE_STRUCTURED_UNITS + extraStructuralUnits, aInfo);
        _status = OFFLINE;
        _epsInfo = aInfo;
        _supplierList = new ArrayList();
        _consumerList = new ArrayList();
        _flow = 0;
        _amountEnergySupplied = 0;
        _amountEnergyConsumed = 0;
        reset();
        toInfo();
    }

    public void turnOn() {
        _status = ONLINE;
        _flow = TRANSFER_ENERGY_UNIT * _structuralUnits; 
        toInfo();
    }

    public void turnOff() {
        _status = OFFLINE;
        _flow = 0;

        reset();
        toInfo();
    }

    public void register(ISupplierableComponent aSupplier) {
        _supplierList.add(aSupplier);
    }
    
    public void register(IConsumerableComponent aConsumer) {
        _consumerList.add(aConsumer);
    }    
    

    public void timed() {
        if (!running()) 
            return;

        reset();
        supply();
        _amountEnergySupplied = _amountEnergy;
        check();
        consume();
        _amountEnergyConsumed = _amountEnergySupplied - _amountEnergy;
        toInfo();
    }

    protected void toInfo() {
        _epsInfo.status(_status);
        _epsInfo.flow(_flow);
        _epsInfo.energySupplied(_amountEnergySupplied);
        _epsInfo.energyConsumed(_amountEnergyConsumed);

    }
    
    private boolean running() {
        return _status.equals(ONLINE);
    }    
    
    private void reset() {
        _amountEnergy = 0;
        _amountEnergySupplied = 0;
        _amountEnergyConsumed = 0;
    }
    

    private void check() {
      
        if (_amountEnergy > _flow) {
            _amountEnergy =_flow;
        }
    }

    private void supply() {
        Iterator supplierIterator =_supplierList.listIterator();
        while (supplierIterator.hasNext()) {
            _amountEnergy += ((ISupplierableComponent)supplierIterator.next()).supply() ;
        }
    }    
    
    private void consume() {
        Iterator consumerIterator =_consumerList.listIterator();
        while (consumerIterator.hasNext()) {
            _amountEnergy = ((IConsumerableComponent)consumerIterator.next()).consume(_amountEnergy) ;
        }
    }

}
